/**
 * 性能监控工具
 * 监控游戏性能指标，包括FPS、内存使用、渲染时间等
 * @class
 */

export interface PerformanceMetrics {
  /** 当前FPS */
  fps: number
  /** 平均FPS */
  averageFps: number
  /** 最低FPS */
  minFps: number
  /** 最高FPS */
  maxFps: number
  /** 内存使用情况（MB） */
  memoryUsage: {
    used: number
    total: number
    percentage: number
  }
  /** 渲染时间（毫秒） */
  renderTime: number
  /** 更新时间（毫秒） */
  updateTime: number
  /** 总帧数 */
  totalFrames: number
  /** 运行时间（秒） */
  runtime: number
}

export interface PerformanceThresholds {
  /** 最低可接受FPS */
  minAcceptableFps: number
  /** 内存使用警告阈值（MB） */
  memoryWarningThreshold: number
  /** 渲染时间警告阈值（毫秒） */
  renderTimeWarningThreshold: number
}

/**
 * 性能监控器类
 */
export class PerformanceMonitor {
  private isMonitoring: boolean = false
  private startTime: number = 0
  private lastFrameTime: number = 0
  private frameCount: number = 0
  private fpsHistory: number[] = []
  private maxFpsHistorySize: number = 60 // 保存最近60帧的FPS数据
  
  private renderTimeHistory: number[] = []
  private updateTimeHistory: number[] = []
  private maxTimeHistorySize: number = 30
  
  private thresholds: PerformanceThresholds = {
    minAcceptableFps: 30,
    memoryWarningThreshold: 100,
    renderTimeWarningThreshold: 16.67 // 60fps对应的帧时间
  }
  
  private warningCallbacks: Array<(warning: string, metrics: PerformanceMetrics) => void> = []

  /**
   * 创建性能监控器实例
   * @param thresholds - 性能阈值配置
   */
  constructor(thresholds?: Partial<PerformanceThresholds>) {
    if (thresholds) {
      this.thresholds = { ...this.thresholds, ...thresholds }
    }
  }

  /**
   * 开始性能监控
   */
  startMonitoring(): void {
    if (this.isMonitoring) {
      return
    }

    this.isMonitoring = true
    this.startTime = performance.now()
    this.lastFrameTime = this.startTime
    this.frameCount = 0
    this.fpsHistory = []
    this.renderTimeHistory = []
    this.updateTimeHistory = []

    console.log('性能监控已启动')
  }

  /**
   * 停止性能监控
   */
  stopMonitoring(): void {
    this.isMonitoring = false
    console.log('性能监控已停止')
  }

  /**
   * 记录帧开始时间
   * @returns 帧开始时间戳
   */
  frameStart(): number {
    if (!this.isMonitoring) {
      return performance.now()
    }

    const currentTime = performance.now()
    const deltaTime = currentTime - this.lastFrameTime

    if (deltaTime > 0) {
      const fps = 1000 / deltaTime
      this.fpsHistory.push(fps)
      
      if (this.fpsHistory.length > this.maxFpsHistorySize) {
        this.fpsHistory.shift()
      }
    }

    this.lastFrameTime = currentTime
    this.frameCount++

    return currentTime
  }

  /**
   * 记录渲染时间
   * @param startTime - 渲染开始时间
   */
  recordRenderTime(startTime: number): void {
    if (!this.isMonitoring) {
      return
    }

    const renderTime = performance.now() - startTime
    this.renderTimeHistory.push(renderTime)
    
    if (this.renderTimeHistory.length > this.maxTimeHistorySize) {
      this.renderTimeHistory.shift()
    }

    // 检查渲染时间警告
    if (renderTime > this.thresholds.renderTimeWarningThreshold) {
      this.triggerWarning(`渲染时间过长: ${renderTime.toFixed(2)}ms`)
    }
  }

  /**
   * 记录更新时间
   * @param startTime - 更新开始时间
   */
  recordUpdateTime(startTime: number): void {
    if (!this.isMonitoring) {
      return
    }

    const updateTime = performance.now() - startTime
    this.updateTimeHistory.push(updateTime)
    
    if (this.updateTimeHistory.length > this.maxTimeHistorySize) {
      this.updateTimeHistory.shift()
    }
  }

  /**
   * 获取当前性能指标
   * @returns 性能指标对象
   */
  getMetrics(): PerformanceMetrics {
    const currentTime = performance.now()
    const runtime = (currentTime - this.startTime) / 1000

    // 计算FPS统计
    const currentFps = this.fpsHistory.length > 0 ? this.fpsHistory[this.fpsHistory.length - 1] : 0
    const averageFps = this.fpsHistory.length > 0 
      ? this.fpsHistory.reduce((sum, fps) => sum + fps, 0) / this.fpsHistory.length 
      : 0
    const minFps = this.fpsHistory.length > 0 ? Math.min(...this.fpsHistory) : 0
    const maxFps = this.fpsHistory.length > 0 ? Math.max(...this.fpsHistory) : 0

    // 计算渲染时间
    const renderTime = this.renderTimeHistory.length > 0
      ? this.renderTimeHistory.reduce((sum, time) => sum + time, 0) / this.renderTimeHistory.length
      : 0

    // 计算更新时间
    const updateTime = this.updateTimeHistory.length > 0
      ? this.updateTimeHistory.reduce((sum, time) => sum + time, 0) / this.updateTimeHistory.length
      : 0

    // 获取内存使用情况
    const memoryUsage = this.getMemoryUsage()

    return {
      fps: currentFps,
      averageFps,
      minFps,
      maxFps,
      memoryUsage,
      renderTime,
      updateTime,
      totalFrames: this.frameCount,
      runtime
    }
  }

  /**
   * 获取内存使用情况
   * @returns 内存使用信息
   */
  private getMemoryUsage(): { used: number; total: number; percentage: number } {
    // 检查是否支持 performance.memory API
    if ('memory' in performance && (performance as any).memory) {
      const memory = (performance as any).memory
      const used = memory.usedJSHeapSize / (1024 * 1024) // 转换为MB
      const total = memory.totalJSHeapSize / (1024 * 1024)
      const percentage = total > 0 ? (used / total) * 100 : 0

      // 检查内存使用警告
      if (used > this.thresholds.memoryWarningThreshold) {
        this.triggerWarning(`内存使用过高: ${used.toFixed(2)}MB`)
      }

      return { used, total, percentage }
    }

    return { used: 0, total: 0, percentage: 0 }
  }

  /**
   * 添加警告回调函数
   * @param callback - 警告回调函数
   */
  onWarning(callback: (warning: string, metrics: PerformanceMetrics) => void): void {
    this.warningCallbacks.push(callback)
  }

  /**
   * 触发性能警告
   * @param warning - 警告信息
   */
  private triggerWarning(warning: string): void {
    const metrics = this.getMetrics()
    
    // 检查FPS警告
    if (metrics.fps < this.thresholds.minAcceptableFps) {
      warning += ` (当前FPS: ${metrics.fps.toFixed(1)})`
    }

    console.warn(`性能警告: ${warning}`)
    
    this.warningCallbacks.forEach(callback => {
      try {
        callback(warning, metrics)
      } catch (error) {
        console.error('性能警告回调执行失败:', error)
      }
    })
  }

  /**
   * 生成性能报告
   * @returns 格式化的性能报告字符串
   */
  generateReport(): string {
    const metrics = this.getMetrics()
    
    return `
性能监控报告
====================
运行时间: ${metrics.runtime.toFixed(2)}秒
总帧数: ${metrics.totalFrames}

FPS统计:
- 当前FPS: ${metrics.fps.toFixed(1)}
- 平均FPS: ${metrics.averageFps.toFixed(1)}
- 最低FPS: ${metrics.minFps.toFixed(1)}
- 最高FPS: ${metrics.maxFps.toFixed(1)}

时间统计:
- 平均渲染时间: ${metrics.renderTime.toFixed(2)}ms
- 平均更新时间: ${metrics.updateTime.toFixed(2)}ms

内存使用:
- 已使用: ${metrics.memoryUsage.used.toFixed(2)}MB
- 总计: ${metrics.memoryUsage.total.toFixed(2)}MB
- 使用率: ${metrics.memoryUsage.percentage.toFixed(1)}%
====================
    `.trim()
  }

  /**
   * 重置监控数据
   */
  reset(): void {
    this.frameCount = 0
    this.fpsHistory = []
    this.renderTimeHistory = []
    this.updateTimeHistory = []
    this.startTime = performance.now()
    this.lastFrameTime = this.startTime
  }

  /**
   * 检查是否正在监控
   * @returns 是否正在监控
   */
  isActive(): boolean {
    return this.isMonitoring
  }
}

/**
 * 全局性能监控器实例
 */
export const performanceMonitor = new PerformanceMonitor()